package cn.itsource.ymcc.service.impl;

import cn.itsource.ymcc.common.jwt.JwtUtils;
import cn.itsource.ymcc.common.jwt.PayloadData;
import cn.itsource.ymcc.common.jwt.RsaUtils;
import cn.itsource.ymcc.common.result.JsonResult;
import cn.itsource.ymcc.common.util.AssertUtil;
import cn.itsource.ymcc.domain.Login;
import cn.itsource.ymcc.domain.User;
import cn.itsource.ymcc.dto.LoginDto;
import cn.itsource.ymcc.mapper.LoginMapper;
import cn.itsource.ymcc.openfeign.UserFeignClient;
import cn.itsource.ymcc.service.ILoginService;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.FileCopyUtils;

import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.spec.InvalidKeySpecException;
import java.util.HashMap;
import java.util.Map;

/**
 * <p>
 * 登录表 服务实现类
 * </p>
 *
 * @author zcj
 * @since 2023-11-26
 */
@Service
public class LoginServiceImpl extends ServiceImpl<LoginMapper, Login> implements ILoginService {
    @Autowired
    private LoginMapper loginMapper;
    @Autowired
    private UserFeignClient userFeignClient;
    /**
     * 登录
     * @param loginDto
     * @return
     */
    @Override
    public Object accountLogin(LoginDto loginDto) {
        Login login = loginMapper.selectOne(new LambdaQueryWrapper<Login>()
                .eq(Login::getUsername, loginDto.getUsername()));
        AssertUtil.isNotNull(login,"为查询到该用户");
        //密码校验
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        boolean matches = bCryptPasswordEncoder.matches(loginDto.getPassword(), login.getPassword());
        AssertUtil.isTrue(matches,"用户名或密码错误");

        login.setPassword("");
        //完成登录
        return loginSuccess(login,loginDto.getType());
    }

    @Override
    public JsonResult common(LoginDto loginDto) {
        //去数据库查询 看有没有 账号
        Login login = loginMapper.selectOne(new LambdaQueryWrapper<Login>()
                .eq(Login::getUsername, loginDto.getUsername())
                .eq(Login::getType, loginDto.getType()));
        AssertUtil.isNotNull(login,"账号或者密码不正确！");
        //验证密码
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        boolean matches = bCryptPasswordEncoder.matches(loginDto.getPassword(), login.getPassword());
        AssertUtil.isTrue(matches,"账号或者密码不正确！");

        //返回用户信息  --- ？
        JsonResult jsonResult = userFeignClient.loginId(login.getId());
        AssertUtil.isNotNull(jsonResult.getData(),"服务繁忙，请稍后重试");
        Object data = jsonResult.getData();//通过远程服务调用返回对象变成了LinkedHashMap
        //解决方案 先转json 在转对象
        String jsonString = JSON.toJSONString(data); //将对象转json字符串
        User user = JSON.parseObject(jsonString, User.class);//将json字符串转对象
        System.out.println(user);
        //返回token  --- jwt
        Map<String, String> stringStringMap = loginSuccess(user,loginDto.getType());
        return JsonResult.success().setData(stringStringMap);
    }

    /**
     * 专门处理登录成功的业务
     * @param login
     * @return
     */
    private Map<String, String> loginSuccess(Object userInfo,Integer type) {
        Map<String, String> map = new HashMap<>();
        try {
            //1.用户类型为0的时候（后台管理系统用户），连表查询当前登录用户拥有的权限和菜单  [今天先不做]
            //2.JWT工具类生成JWT字符串  私钥加密  公钥解密
            PrivateKey privateKey = RsaUtils
                    .getPrivateKey(FileCopyUtils
                            .copyToByteArray(this.getClass().getClassLoader().getResourceAsStream("hrm_auth_rsa")));
            //加密得到token
            PayloadData payloadData = new PayloadData();
//            login.setPassword(null);    //置空密码，更安全
            if(type == 0){
                payloadData.setLogin(userInfo);
            }else {
                payloadData.setUser(userInfo);
            }


            String token = JwtUtils.generateTokenExpireInMinutes(payloadData, privateKey, 60*24);  //24小时过期

            //3.封装到HashMap
            map.put("token", token);
            map.put("currentUser", JSON.toJSONString(userInfo));
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeySpecException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return map;
    }



    //    public static void main(String[] args) {
//        //比较密码  使用springSecurity 密码加密
//        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
//        String encode = bCryptPasswordEncoder.encode("123456");
//        System.out.println(encode);
//
//        boolean matches = bCryptPasswordEncoder.matches("1213456",encode);
//        System.out.println(matches);
//
//    }
}
